package top.fwpsl.java.util.stream;

import top.fwpsl.data.Data;
import top.fwpsl.data.PersonModel;

import java.util.*;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * @author 风戏fw
 */
public class Demo {

    public static void main(String[] args) {
//        test_stream_02();
//        test_stream_07(Data.getData2());
        test_stream_08(Data.getDate());
    }

    //数值流
    private static void test_stream_01() {
        //由于拆箱和装箱会很耗时，
        // 所以针对基本数值类型提供了三种对应的包装类型的Stream：IntStream、LongStream、DoubleStream
        IntStream.of(new int[]{1, 2, 3}).forEach(System.out::print);
        System.out.println();
        //range，需要传入开始节点和结束节点两个参数，返回的是一个有序的IntStream
        //包含开始节点和结束节点两个参数之间所有的参数，间隔为1.
        IntStream.range(1, 3).forEach(System.out::print);
        System.out.println();
        //rangeClosed的功能和range类似。差别就是rangeClosed包含最后的结束节点，range不包含。
        IntStream.rangeClosed(1, 3).forEach(System.out::print);
    }

    private static void test_stream_02() {
        List<PersonModel> list = Data.getDate();
        Map<String, PersonModel> personMap = list.stream()
                .filter(per -> "女".equals(per.getSex()))
                .collect(Collectors.toMap(per -> per.getName(), per -> per));

        personMap.forEach((key,value) -> System.out.println(key + "\t" + value));
        System.out.println();

        Map<String, List<PersonModel>> map = list.stream()
                .collect(Collectors.groupingBy(per -> per.getSex()));
        System.out.println(map);
        System.out.println();

        list.stream().sorted(PersonModel::compareTo).forEachOrdered(System.out:: println);
        System.out.println();

        Predicate<PersonModel> predicate = pre -> pre.getAge() < 35;
        Predicate<PersonModel> predicate2 = pre -> "男".equals(pre.getSex());
        String str = list.stream().filter(predicate.negate().and(predicate2))
                .map(per -> per.toString())
                .collect(Collectors.joining(",", "[", "]"));

        System.out.println(str);
        System.out.println();

        list.stream().map(personModel -> personModel.getName().toUpperCase()).forEach(System.out::println);
        System.out.println();

        list.stream().flatMap(personModel -> Stream.of(personModel.getName().toUpperCase())).forEach(System.out::println);
    }

    private static void test_stream_03() {
        Optional<PersonModel> person = Data.getDate().stream().max(PersonModel::compareTo);
        System.out.println(person);

        person = Data.getDate().stream().min(PersonModel::compareTo);
        System.out.println(person);

        System.out.println(Data.getDate().stream().filter(per -> "男".equals(per.getSex())).count());
    }

    private static void test_stream_04()  {
        Stream.generate(new Random()::nextLong).limit(10).forEach(System.out::println);
        System.out.println();
        //采用IntStream流的方式(推荐使用 逼格很高)
        IntStream.generate(() -> (int) (System.nanoTime() % 100)).
                limit(10).forEach(System.out::println);
    }

    /**
     * 分页功能
     * limit(long), skip(long)
     */
    private static void test_stream_05(List data, int page, int size) {
        data.stream().sorted().forEach(System.out::println);
        System.out.println();
        data.stream().sorted().skip((page - 1) * size).limit(size).forEach(System.out::println);
    }

    //peek(Consumer)方法，数据加功
    private static void test_stream_06(List<PersonModel> data) {
        data.stream().forEach(System.out::println);
        System.out.println();
        data.stream().peek(per -> {
            per.setName(per.getName().toUpperCase());
            per.setSex("男".equals(per.getSex())? "boy": "girl");
        }).forEach(System.out::println);
    }

    //distinct()方法，数据去重
    private static void test_stream_07(List<PersonModel> data) {
        data.stream().forEach(System.out::println);
        System.out.println();
        data.stream().distinct().forEach(System.out::println);
    }

    private static void test_stream_08(List<PersonModel> data) {
        System.out.println("是否所有人年龄都小于50岁：" + data.stream().allMatch(person -> person.getAge() < 50));
        System.out.println("是否所有人年龄都小于40岁：" + data.stream().allMatch(person -> person.getAge() < 40));
        System.out.println();
        System.out.println("是否有人年龄都小于30岁：" + data.stream().anyMatch(person -> person.getAge() < 30));
        System.out.println("是否有人年龄都小于20岁：" + data.stream().anyMatch(person -> person.getAge() < 20));
        System.out.println();
        System.out.println("是否没有小于20岁的人：" + data.stream().noneMatch(person -> person.getAge() < 20));
        System.out.println("是否没有小于30岁的人：" + data.stream().noneMatch(person -> person.getAge() < 30));
    }
}
